#include "dialog_settings.h"
#include "mainwindow.h"
#include "ui_dialog_settings.h"

Dialog_settings::Dialog_settings(QWidget *parent, NetElementType entype /* 0 - node, 1 - edge*/) :
    QDialog(parent),
    ui(new Ui::Dialog_settings)
{
    ui->setupUi(this);
    model = new GraphItemModel();
    model->setColumnCount(1);
    model->setRowCount(1);
    model->setBalRow(m_bal_row);

    if (entype == ET_NODE)
        delegate = new NodeDelegate;
    else if (entype == ET_EDGE)
        delegate = new EdgeDelegate;

    setentype(entype);

    ui->tableView->setModel(model);
    ui->tableView->setItemDelegate(delegate);
}

Dialog_settings::~Dialog_settings()
{
    if (ui)
        delete ui;
    if (delegate)
        delete delegate;
}

void Dialog_settings::SetColHeaderData(int colnumber, QString caption)
{
    model->setHeaderData(colnumber,Qt::Horizontal,caption);
}

void Dialog_settings::SetModelArgument(int col, int row)
{
    model->setRowCount(row);
    model->setColumnCount(col);
}

void Dialog_settings::SetIndexValue (int row, int col, QVariant value )
{
    QModelIndex index = model->index(row, col, QModelIndex());
    model->setData(index, value);
}

void Dialog_settings::GetIndexValue (int row, int col, QVariant &value )
{
    QModelIndex index = model->index(row, col, QModelIndex());
    value = model->data(index);
}

void Dialog_settings::setBal(int bal)
{
    m_bal_row = bal;
}

int Dialog_settings::getBal()
{
    return m_bal_row;
}

void Dialog_settings::on_pushButton_ok_clicked()
{
    int row = model->rowCount();
    NetElementType entype = getentype();

    QVariant value;
    if (entype == ET_EDGE)
    {
        QList<double> edge_resist_R;
        QList<double> edge_resist_X;
        QList<double> edge_power_a;
        QList<double> edge_power_r;
        QList<double> edge_otr_pow_a;
        QList<double> edge_pol_pow_a;


        QList<int> edge_state;

        for (int i=0; i<row; i++)
        {
            GetIndexValue(i, 1, value);
            if (value.toString().toLower() == "отключена")
                edge_state.push_back(0);
            else
                edge_state.push_back(1);

            GetIndexValue(i, 2, value);
            edge_resist_R.push_back(value.toDouble());

            GetIndexValue(i, 3, value);
            edge_resist_X.push_back(value.toDouble());

            GetIndexValue(i, 4, value);
            edge_power_a.push_back(value.toDouble());

            GetIndexValue(i, 5, value);
            edge_power_r.push_back(value.toDouble());

            GetIndexValue(i, 6, value);
            edge_otr_pow_a.push_back(value.toDouble());

            GetIndexValue(i, 7, value);
            edge_pol_pow_a.push_back(value.toDouble());
        }

        emit EdgeDataChanged(edge_state, edge_resist_R, edge_resist_X,
                             edge_power_a, edge_power_r,
                             edge_otr_pow_a, edge_pol_pow_a);
    }
    else if (entype == ET_NODE)
    {
        QList<int> node_state;
        QList<double> node_voltage;
        QList<double> node_a_power;
        QList<double> node_r_power;
        QList<double> node_max_pow;
        QList<double> node_min_pow;

        for (int i=0; i<row; i++)
        {
            GetIndexValue(i, 1, value);
            if (value.toString().toLower() == "отключен")
                node_state.push_back(0);
            else
                node_state.push_back(1);

            GetIndexValue(i, 2, value);
            node_voltage.push_back(value.toDouble());

            GetIndexValue(i, 3, value);
            node_a_power.push_back(value.toDouble());

            GetIndexValue(i, 4, value);
            node_r_power.push_back(value.toDouble());

            GetIndexValue(i, 5, value);
            node_max_pow.push_back(value.toDouble());

            GetIndexValue(i, 6, value);
            node_min_pow.push_back(value.toDouble());
        }

        emit NodeDataChanged(node_state, node_voltage,
                             node_a_power, node_r_power,
                             node_max_pow, node_min_pow);
    }

    close();
}

void Dialog_settings::on_pushButton_cancel_clicked()
{
    close();
}

void  Dialog_settings::setentype(NetElementType entype)
{
    m_entype = entype;
}

NetElementType Dialog_settings::getentype()
{
    return m_entype;
}

// ***********************************************************************
//  EdgeDelegate
// ***********************************************************************

EdgeDelegate::EdgeDelegate(QObject *parent) :
    GraphDelegate(parent)
{
}

// Создает виджет для отображения
QWidget *EdgeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    int indx = index.column();

    if (indx == 0)
    {
        return 0;
    }
    else if(indx != 1 && indx != 0)
    {
        QDoubleSpinBox *editor = new QDoubleSpinBox(parent);
        editor->setSingleStep(0.1);
        if (indx == 2)
            editor->setMaximum(100);
        else
            editor->setMaximum(1000);

        editor->setMinimum(0);
        return editor;
    }
    else if(indx == 1)
    {
        QComboBox *editor = new QComboBox(parent);
        editor->addItem(QIcon(":/icons/yes.png"),"Включена");
        editor->addItem(QIcon(":/icons/stop.png"),"Отключена");
        editor->setCurrentIndex(0);
        return editor;
    }
    else
        return QItemDelegate::createEditor(parent, option, index);
}

// Устанавливает данные в виджете редактирования
void    EdgeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    int indx = index.column();
    if (indx == 0)
    {
        //
    }
    else if(indx != 1 && indx != 0)
    {
        double value = index.model()->data(index, Qt::EditRole).toDouble();

        QDoubleSpinBox *spinbox = static_cast<QDoubleSpinBox*>(editor);
        spinbox->setValue(value);
    }
    else if(indx == 1)
    {
        QString currentText = index.model()->data(index, Qt::DisplayRole).toString();
        QComboBox *cmbbox = static_cast<QComboBox*>(editor);
    }
    else
        QItemDelegate::setEditorData(editor, index);
}

// Извлекает данные из виджета редактирования и передает их модели
void    EdgeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    int indx = index.column();

    if (indx == 0)
    {
        //
    }
    else if(indx != 1 && indx != 0)
    {
        QDoubleSpinBox *spinbox = static_cast<QDoubleSpinBox*>(editor);
        spinbox->interpretText();
        double value = spinbox->value();
        model->setData(index,value, Qt::EditRole);
    }
    if(indx == 1)
    {
        QComboBox *cmbbox = static_cast<QComboBox*>(editor);
        model->setData(index, cmbbox->currentText(), Qt::DisplayRole);
    }
    else
        QItemDelegate::setModelData(editor, model, index);
}


void    EdgeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    editor->setGeometry(option.rect);
}


// ***********************************************************************
//  NodeDelegate
// ***********************************************************************
NodeDelegate::NodeDelegate(QObject *parent) :
    GraphDelegate(parent)
{
}

// Создает виджет для отображения
QWidget *NodeDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    int indx_col = index.column();

    if (indx_col == 0)
    {
        return 0;
    }
    else if(indx_col == 1)
    {
        QComboBox *editor = new QComboBox(parent);
        editor->addItem(QIcon(":/icons/yes.png"),"Включен");
        editor->addItem(QIcon(":/icons/stop.png"),"Отключен");
        editor->setCurrentIndex(0);
        return editor;
    }
    else if(indx_col != 1 && indx_col != 0)
    {
        QDoubleSpinBox *editor = new QDoubleSpinBox(parent);
        if (indx_col == 2)
        {
            editor->setSingleStep(1.0);
            editor->setMaximum(1000);
        }
        else
        {
            editor->setSingleStep(0.1);
            editor->setMaximum(1000);
            editor->setMinimum(-1000);
        }

        editor->setMinimum(-1000);
        //editor->setMinimum(0);
        return editor;
    }
    else
        return QItemDelegate::createEditor(parent, option, index);
}

// Устанавливает данные в виджете редактирования
void    NodeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    int indx_col = index.column();

    if (indx_col == 0)
    {
        //
    }
    else if(indx_col == 1)
    {
        QString currentText = index.model()->data(index, Qt::DisplayRole).toString();
        QComboBox *cmbbox = static_cast<QComboBox*>(editor);
    }
    else if(indx_col != 1 && indx_col != 0)
    {
        double value = index.model()->data(index, Qt::EditRole).toDouble();

        QDoubleSpinBox *spinbox = static_cast<QDoubleSpinBox*>(editor);
        spinbox->setValue(value);
    }
    else
        QItemDelegate::setEditorData(editor, index);
}

// Извлекает данные из виджета редактирования и передает их модели
void    NodeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    int indx = index.column();

    if (indx == 0)
    {
        //
    }
    else if(indx != 1 && indx != 0)
    {
        QDoubleSpinBox *spinbox = static_cast<QDoubleSpinBox*>(editor);
        spinbox->interpretText();
        double value = spinbox->value();
        model->setData(index,value, Qt::EditRole);
    }
    if(indx == 1)
    {
        QComboBox *cmbbox = static_cast<QComboBox*>(editor);
        model->setData(index, cmbbox->currentText(), Qt::DisplayRole);
    }
    else
        QItemDelegate::setModelData(editor, model, index);
}

void NodeDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    editor->setGeometry(option.rect);
}

// GraphDelegate
GraphDelegate::GraphDelegate(QObject *parent)
{
}


// GraphItemModel
Qt::ItemFlags GraphItemModel::flags(const QModelIndex &index) const
{
    if(index.row() == (m_bal_row+1))
           return Qt::ItemIsEnabled | Qt::ItemIsSelectable;

    return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}

//QVariant GraphItemModel::data(const QModelIndex &index, int role) const
//{
//    int row = index.row();
//    int col = index.column();

//    switch(role){
//    case Qt::BackgroundRole:
//       if (row == m_bal_row && col == 2)
//       {
//           QBrush redBackground(Qt::red);
//           return redBackground;
//       }
//       break;
//    }
//    return QVariant();
//}

void GraphItemModel::setBalRow(int bal_row)
{
    m_bal_row = bal_row;
}

GraphItemModel::GraphItemModel(QObject *parent)
{
}
